package org.jetlinks.pro.rule.engine.configuration;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hswebframework.web.authorization.Authentication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Nonnull;
import java.util.List;
import java.util.Set;

@Getter
@Setter
@ConfigurationProperties(prefix = "rule.engine")
public class RuleEngineProperties {

    private String clusterName = "jetlinks";

    private String serverId = "default";

    private String serverName = "default";


    @Nonnull
    private ExecutorFilter executorFilter = new ExecutorFilter();

    @Getter
    @Setter
    public static class ExecutorFilter {
        private boolean enabled = false;

        private PermissionStrategy permission;
        private DimensionStrategy dimension;

        private Set<String> includes;
        private Set<String> excludes;

        public boolean test(Authentication auth, String taskExecutor) {
            if (!enabled) {
                return true;
            }
            //排除的executor
            if (!CollectionUtils.isEmpty(excludes) && excludes.contains(taskExecutor)) {
                return true;
            }
            //不是指定的executor
            if (!CollectionUtils.isEmpty(includes) && !includes.contains(taskExecutor)) {
                return true;
            }
            boolean passed = false;
            if (permission != null) {
                passed = permission.test(auth, taskExecutor);
            }
            if (!passed && dimension != null) {
                passed = dimension.test(auth, taskExecutor);
            }
            return passed;
        }
    }

    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    public static class DimensionStrategy implements ExecutorFilterStrategy {
        private String type;
        private List<String> ids;

        @Override
        public boolean test(Authentication auth, String taskExecutor) {
            if (StringUtils.isEmpty(type) || CollectionUtils.isEmpty(ids)) {
                return false;
            }
            return auth.hasDimension(type, ids);
        }
    }

    @Getter
    @Setter
    public static class PermissionStrategy implements ExecutorFilterStrategy {
        //根据权限控制
        private String permissionId = "rule-task-executor";
        //使用executor当作action
        private boolean executorAsAction = true;

        @Override
        public boolean test(Authentication auth, String taskExecutor) {
            return executorAsAction ?
                auth.hasPermission(permissionId, taskExecutor) :
                auth.hasPermission(permissionId);
        }
    }

    public interface ExecutorFilterStrategy {

        boolean test(Authentication auth, String taskExecutor);

    }
}
